const Panel = imports.ui.panel;
const Overlay = imports.ui.overlay;
const RunDialog = imports.ui.run_dialog;
+const WindowManager = imports.ui.windowmanager;
const DEFAULT_BACKGROUND_COLOR = new Clutter.Color();
DEFAULT_BACKGROUND_COLOR.from_pixel(0x2266bbff);
let panel = null;
let overlay = null;
let run_dialog = null;
+let wm = null;
function start() {
let global = Shell.global_get();
});
panel = new Panel.Panel();
- overlay = new Overlay.Overlay();
global.set_stage_input_area(0, 0, global.screen_width, Panel.PANEL_HEIGHT);
+
+ overlay = new Overlay.Overlay();
+ wm = new WindowManager.WindowManager();
}
function show_overlay() {
--- /dev/null
+/* -*- mode: js2; js2-basic-offset: 4; -*- */
+
+const Clutter = imports.gi.Clutter;
+const Mainloop = imports.mainloop;
+const Shell = imports.gi.Shell;
+
+const Main = imports.ui.main;
+
+function WindowManager(shellwm) {
+ this._init(shellwm);
+}
+
+WindowManager.prototype = {
+ _init : function(shellwm) {
+ let global = Shell.global_get();
+ let shellwm = global.window_manager;
+
+ shellwm.connect('switch-workspace',
+ function(o, from, to, direction) {
+ let actors = shellwm.get_switch_workspace_actors();
+ for (let i = 0; i < actors.length; i++) {
+ if (actors[i].get_workspace() == from)
+ actors[i].hide();
+ else if (actors[i].get_workspace() == to)
+ actors[i].show();
+ }
+ });
+ }
+};
plugindir = $(libdir)/metacity/plugins/clutter
plugin_LTLIBRARIES = libgnome-shell.la
+shell_built_sources = \
+ shell-marshal.h \
+ shell-marshal.c
+
+BUILT_SOURCES += $(shell_built_sources)
+
+SHELL_STAMP_FILES = stamp-shell-marshal.h
+CLEANFILES += $(SHELL_STAMP_FILES)
+
libgnome_shell_la_SOURCES = \
+ $(shell_built_sources) \
gnome-shell-plugin.c \
shell-app-monitor.c \
shell-app-monitor.h \
shell-global.c \
shell-global.h \
shell-tray-manager.c \
- shell-tray-manager.h
+ shell-tray-manager.h \
+ shell-wm.c \
+ shell-wm.h
+
+shell-marshal.h: stamp-shell-marshal.h
+ @true
+stamp-shell-marshal.h: Makefile shell-marshal.list
+ $(GLIB_GENMARSHAL) \
+ --prefix=_shell_marshal \
+ --header \
+ $(srcdir)/shell-marshal.list > xgen-tmh && \
+ (cmp -s xgen-tmh shell-marshal.h || cp -f xgen-tmh shell-marshal.h) && \
+ rm -f xgen-tmh && \
+ echo timestamp > $(@F)
+
+shell-marshal.c: Makefile shell-marshal.list
+ (echo "#include \"shell-marshal.h\"" ; \
+ $(GLIB_GENMARSHAL) \
+ --prefix=_shell_marshal \
+ --body \
+ $(srcdir)/shell-marshal.list ) > xgen-tmc && \
+ cp -f xgen-tmc shell-marshal.c && \
+ rm -f xgen-tmc
libgnome_shell_la_LDFLAGS = -avoid-version -module
libgnome_shell_la_LIBADD = \
/* Event handling */
plugin->xevent_filter = xevent_filter;
+ /* This will also create the ShellWM, which will set the appropriate
+ * window management callbacks in plugin.
+ */
+ _shell_global_set_plugin (shell_global_get(), plugin);
+
return NULL;
}
plugin_state->gjs_context = gjs_context_new_with_search_path(search_path);
g_strfreev(search_path);
- _shell_global_set_plugin (shell_global_get(), plugin);
-
plugin_state->panel_action = XInternAtom (meta_display_get_xdisplay (display),
"_GNOME_PANEL_ACTION", FALSE);
plugin_state->panel_action_run_dialog = XInternAtom (meta_display_get_xdisplay (display),
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
#include "shell-global.h"
+#include "shell-wm.h"
#include "display.h"
#include <clutter/x11/clutter-x11.h>
GObject parent;
MutterPlugin *plugin;
+ ShellWM *wm;
};
enum {
PROP_SCREEN_WIDTH,
PROP_SCREEN_HEIGHT,
PROP_STAGE,
- PROP_WINDOW_GROUP
+ PROP_WINDOW_GROUP,
+ PROP_WINDOW_MANAGER
};
/* Signals */
case PROP_WINDOW_GROUP:
g_value_set_object (value, mutter_plugin_get_window_group (global->plugin));
break;
+ case PROP_WINDOW_MANAGER:
+ g_value_set_object (value, global->wm);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
"Actor holding window actors",
CLUTTER_TYPE_ACTOR,
G_PARAM_READABLE));
+ g_object_class_install_property (gobject_class,
+ PROP_WINDOW_MANAGER,
+ g_param_spec_object ("window-manager",
+ "Window Manager",
+ "Window management interface",
+ SHELL_TYPE_WM,
+ G_PARAM_READABLE));
}
/**
MutterPlugin *plugin)
{
g_return_if_fail (SHELL_IS_GLOBAL (global));
+ g_return_if_fail (global->plugin == NULL);
global->plugin = plugin;
+ global->wm = shell_wm_new (plugin);
}
/**
Window stagewin = clutter_x11_get_stage_window (stage);
XSetInputFocus (xdisplay, stagewin, RevertToParent, CurrentTime);
}
+
+ClutterActor *
+shell_global_get_overlay_group (ShellGlobal *global)
+{
+ g_return_val_if_fail (SHELL_IS_GLOBAL (global), NULL);
+
+ return mutter_plugin_get_overlay_group (global->plugin);
+}
+
+ClutterActor *
+shell_global_get_window_group (ShellGlobal *global)
+{
+ g_return_val_if_fail (SHELL_IS_GLOBAL (global), NULL);
+
+ return mutter_plugin_get_window_group (global->plugin);
+}
int width,
int height);
-GList *shell_global_get_windows (ShellGlobal *global);
+GList *shell_global_get_windows (ShellGlobal *global);
+ClutterActor *shell_global_get_window_group (ShellGlobal *global);
+ClutterActor *shell_global_get_overlay_group (ShellGlobal *global);
void _shell_global_set_plugin (ShellGlobal *global,
MutterPlugin *plugin);
--- /dev/null
+VOID:INT,INT,INT
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+#include "shell-wm.h"
+#include "shell-global.h"
+#include "shell-marshal.h"
+
+struct _ShellWM {
+ GObject parent;
+
+ GList *switch_workspace_actors;
+};
+
+/* Signals */
+enum
+{
+#ifdef NOT_YET
+ MINIMIZE,
+ KILL_MINIMIZE,
+ MAXIMIZE,
+ KILL_MAXIMIZE,
+ UNMAXIMIZE,
+ KILL_UNMAXIMIZE,
+ MAP,
+ KILL_MAP,
+ DESTROY,
+ KILL_DESTROY,
+#endif
+ SWITCH_WORKSPACE,
+ KILL_SWITCH_WORKSPACE,
+
+ LAST_SIGNAL
+};
+
+G_DEFINE_TYPE(ShellWM, shell_wm, G_TYPE_OBJECT);
+
+static void shell_wm_set_switch_workspace_actors (ShellWM *wm,
+ GList *actors);
+
+static guint shell_wm_signals [LAST_SIGNAL] = { 0 };
+
+static void
+shell_wm_init (ShellWM *wm)
+{
+}
+
+static void
+shell_wm_finalize (GObject *object)
+{
+ ShellWM *wm = SHELL_WM (object);
+
+ shell_wm_set_switch_workspace_actors (wm, NULL);
+
+ G_OBJECT_CLASS (shell_wm_parent_class)->finalize (object);
+}
+
+static void
+shell_wm_class_init (ShellWMClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = shell_wm_finalize;
+
+ shell_wm_signals[SWITCH_WORKSPACE] =
+ g_signal_new ("switch-workspace",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _shell_marshal_VOID__INT_INT_INT,
+ G_TYPE_NONE, 3,
+ G_TYPE_INT, G_TYPE_INT, G_TYPE_INT);
+ shell_wm_signals[KILL_SWITCH_WORKSPACE] =
+ g_signal_new ("kill-switch-workspace",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static ShellWM *
+shell_wm_get (void)
+{
+ ShellWM *wm;
+
+ g_object_get (shell_global_get (),
+ "window-manager", &wm,
+ NULL);
+ /* drop extra ref added by g_object_get */
+ g_object_unref (wm);
+
+ return wm;
+}
+
+static void
+shell_wm_switch_workspace (const GList **actors,
+ gint from,
+ gint to,
+ MetaMotionDirection direction)
+{
+ ShellWM *wm = shell_wm_get ();
+
+ shell_wm_set_switch_workspace_actors (wm, (GList *)*actors);
+ g_signal_emit (wm, shell_wm_signals[SWITCH_WORKSPACE], 0,
+ from, to, direction);
+ shell_wm_set_switch_workspace_actors (wm, NULL);
+}
+
+static void
+shell_wm_kill_effect (MutterWindow *actor,
+ gulong events)
+{
+ ShellWM *wm = shell_wm_get ();
+
+#ifdef NOT_YET
+ if (events & MUTTER_PLUGIN_MINIMIZE)
+ g_signal_emit (wm, shell_wm_signals[KILL_MINIMIZE], 0);
+ if (events & MUTTER_PLUGIN_MAXIMIZE)
+ g_signal_emit (wm, shell_wm_signals[KILL_MAXIMIZE], 0);
+ if (events & MUTTER_PLUGIN_UNMAXIMIZE)
+ g_signal_emit (wm, shell_wm_signals[KILL_UNMAXIMIZE], 0);
+ if (events & MUTTER_PLUGIN_MAP)
+ g_signal_emit (wm, shell_wm_signals[KILL_MAP], 0);
+ if (events & MUTTER_PLUGIN_DESTROY)
+ g_signal_emit (wm, shell_wm_signals[KILL_DESTROY], 0);
+#endif
+ if (events & MUTTER_PLUGIN_SWITCH_WORKSPACE)
+ g_signal_emit (wm, shell_wm_signals[KILL_SWITCH_WORKSPACE], 0);
+}
+
+
+/**
+ * shell_wm_new:
+ * @plugin: the #MutterPlugin
+ *
+ * Creates a new window management interface by hooking into @plugin.
+ *
+ * Return value: the new window-management interface
+ **/
+ShellWM *
+shell_wm_new (MutterPlugin *plugin)
+{
+#ifdef NOT_YET
+ plugin->minimize = shell_wm_minimize;
+ plugin->maximize = shell_wm_maximize;
+ plugin->unmaximize = shell_wm_unmaximize;
+ plugin->map = shell_wm_map;
+ plugin->destroy = shell_wm_destroy;
+#endif
+ plugin->switch_workspace = shell_wm_switch_workspace;
+ plugin->kill_effect = shell_wm_kill_effect;
+
+ return g_object_new (SHELL_TYPE_WM, NULL);
+}
+
+/**
+ * shell_wm_get_switch_workspace_actors:
+ * @wm: the #ShellWM
+ *
+ * A workaround for a missing feature in gobject-introspection. Returns
+ * the list of windows involved in a switch-workspace operation (which
+ * cannot be passed directly to the signal handler because there's no
+ * way to annotate the element-type of a signal parameter.)
+ *
+ * You must call this from the #ShellWM::switch-workspace signal
+ * handler itself; if you need the value again later, you must save a
+ * copy yourself.
+ *
+ * Return value: (element-type MutterWindow) (transfer full): the list
+ * of windows
+ **/
+GList *
+shell_wm_get_switch_workspace_actors (ShellWM *wm)
+{
+ GList *l;
+
+ for (l = wm->switch_workspace_actors; l; l = l->next)
+ g_object_ref (l->data);
+ return g_list_copy (wm->switch_workspace_actors);
+}
+
+static void
+shell_wm_set_switch_workspace_actors (ShellWM *wm, GList *actors)
+{
+ const GList *l;
+
+ for (l = wm->switch_workspace_actors; l; l = l->next)
+ g_object_unref (l->data);
+ g_list_free (wm->switch_workspace_actors);
+ wm->switch_workspace_actors = g_list_copy (actors);
+ for (l = wm->switch_workspace_actors; l; l = l->next)
+ g_object_ref (l->data);
+}
--- /dev/null
+#ifndef __SHELL_WM_H__
+#define __SHELL_WM_H__
+
+#include <glib-object.h>
+#include <mutter-plugin.h>
+
+G_BEGIN_DECLS
+
+typedef struct _ShellWM ShellWM;
+typedef struct _ShellWMClass ShellWMClass;
+
+#define SHELL_TYPE_WM (shell_wm_get_type ())
+#define SHELL_WM(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SHELL_TYPE_WM, ShellWM))
+#define SHELL_WM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SHELL_TYPE_WM, ShellWMClass))
+#define SHELL_IS_WM(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SHELL_TYPE_WM))
+#define SHELL_IS_WM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SHELL_TYPE_WM))
+#define SHELL_WM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SHELL_TYPE_WM, ShellWMClass))
+
+struct _ShellWMClass
+{
+ GObjectClass parent_class;
+
+};
+
+GType shell_wm_get_type (void) G_GNUC_CONST;
+
+ShellWM *shell_wm_new (MutterPlugin *plugin);
+
+GList *shell_wm_get_switch_workspace_actors (ShellWM *wm);
+
+G_END_DECLS
+
+#endif /* __SHELL_WM_H__ */